1. /* sdfddsub.cpp by K.Tsuru */
  2. // function ID = 322 DRADIX
  3. #ifndef SN_H
  4. #include "sn.h"
  5. #endif
  6. /**********************************************************************
  7. SDouble class
  8. m - n, same sign and |m|>=|n|.
  9. d = m.rdxExp - n.rdxExp
  10. Adjustment figures.
  11. d >= 0
  12. m = v[0].0..0v[mT]....v[mH] * R^(e+d) 0.001234 ^ 10^(5+2)
  13. n = v[0].0..0v[nT]....v[nH] * R^e 0.000456789 ^ 10^5
  14. = 0.00...v[d+nT]....v[d+nH] * R^(e+d) 0.00000456789^ 10^(5+2)
  15. In the fixed point mode it is possible that d < 0.
  16. m = v[0].0..0v[mT]....v[mH] * R^(e+d) 0.1234 ^ 10^(5-2)
  17. n = v[0].0..0v[nT]....v[nH] * R^e 0.000456789 ^ 10^5
  18. = 0.00...v[d+nT]....v[d+nH] * R^(e+d) 0.0456789^ 10^(5-2)
  19. It satisfies mT>= d+nT > 0.
  20. ************************************************************************/
  21. static const char* func = "DDSub"; // add "const" since version 2.192
  22. SDouble DDSub(const SDouble& m, const SDouble& n){
  23. //SDouble only
  24. if((m.Type() != m.REAL)||(n.Type() != n.REAL)) m.SetError(m.RADIX_ERR, func, 322);
  25. if(m.Sign(322) == 0) return -n;
  26. if(n.Sign(322) == 0) return m;
  27. //check sign
  28. if( m.Sign() != n.Sign() ) m.SetError(m.SYNTAX_ERR, func, 322);
  29. //check |m| >> |n|
  30. //"long" type is necessary in the 16 bits system.
  31. long max_fig = (long)m.CurrentMaxSize() -1;
  32. long di = m.NetRdxExp() - n.NetRdxExp();
  33. if( di >= max_fig) return m; // m >> n
  34. int de = m.rdxExp - n.rdxExp; //possible de < 0
  35. SDouble result, N;
  36. const fType* Mf = m.ReadFigures();
  37. const fType* Nf;
  38. uint ml = m.Last(), mf = m.First(), nl, nf;
  39. // step 1 : adjustment of figures
  40. if(de){
  41. N = n; //make copy of n
  42. N.ShiftArray(de);//For de > 0 the size is expanded if necessary.
  43. //If de < 0 and it exceeds the boundary, an overflow error occures.
  44. //This is a syntax error.If |m| > |n| it does not occure.
  45. N.rdxExp += de; //exponent value is used in Sign() bellow
  46. //If N.sign != 0 and the non-zero part is out of range, Sign() returns zero.
  47. if(N.Sign(322) == 0) return m; //check n << m again
  48. Nf = N.ReadFigures(); nl = N.Last(); nf = N.First();
  49. } else{
  50. Nf = n.ReadFigures(); nl = n.Last(); nf = n.First();
  51. }
  52. // step 2 : compare figures
  53. int i, k = 0, top = 0, btm;
  54. if(ml < nl){ //m=0.1, n=0.0823, n has larger
  55. k = -1; btm = (int)nl; top = (int)ml;
  56. } else if(ml > nl){
  57. k = 1; btm = (int)ml; top = (int)nl;
  58. } else btm = (int)ml; //same, in step 3 do not use "top"
  59. uint rsize = (uint)btm+1;
  60. result.valloc(rsize , -1); //does not initialize
  61. result.figure.clear( uint(btm+1) ); //initialize lower part
  62. fType* rf = result.figure.Elements();
  63. #ifndef NDEBUG
  64. result.figure(btm); if(k) assert(btm >= top); // error check
  65. #endif
  66. // step 3 : processing lower part in the case of diffrent figures
  67. // top btm
  68. if(k == -1){ // 0.aaaa bbbb .... 0000 - 0.xxxx yyyy .... zzzz
  69. #ifndef NDEBUG
  70. if(de) N.figure(btm);
  71. #endif
  72. rf[btm] = DRADIX - Nf[btm]; //lowest figure : 10000 - Nf[btm]
  73. fType r1 = DRADIX-1;
  74. for(i = btm-1; i > top; i--) rf[i] = r1 - Nf[i]; // 9999 - Nf[i]
  75. //k has an information of borrowing, then does not let k = 0.
  76. //Here i = top.
  77. // btm top
  78. } else if(k == 1){ //0.aaaa bbbb... cccc - 0.xxxx yyyy 0000 .... 0000
  79. //Copy lower part of m to that of result.
  80. #ifndef NDEBUG
  81. m.figure(btm); // error check
  82. #endif
  83. memcpy(rf+top+1, Mf+top+1, (btm-top)*sizeof(fType));
  84. // for(i = btm; i > top; i--) rf[i] = Mf[i]; // N[i] = 0
  85. i = top; k = 0;
  86. } else i = btm; // k = 0, m and n(or N) have same figures.
  87. // step 4 : It begins subtraction.
  88. top = (int)min(mf, nf);
  89. #ifndef NDEBUG
  90. m.figure(i);
  91. if(N.RawSign() != m.UNDECIDED) N.figure(i); // error check
  92. #endif
  93. int w;
  94. for( ; i >= top; i--){
  95. w = (int)Mf[i] - (int)Nf[i] + k;
  96. // -DRADIX <= w < DRADIX : 16 bits, int type is Ok.
  97. if(w < 0) {
  98. k = -1; w += DRADIX; //borrowing
  99. } else k = 0;
  100. rf[i] = (fType)w;
  101. }
  102. if(top) result.figure.clear(0, uint(top - 1) ); //clear upper part by zero
  103. //If m > n the borrowing k must be equal to zero.
  104. if(k) m.SetError(m.SYNTAX_ERR, "m < n in DDSub", 36);
  105. // step 5 : check the position
  106. while(!rf[top]) top++;
  107. result.aTail = (uint)top;
  108. btm = max((int)ml, (int)nl);
  109. while(!rf[btm]) btm--;
  110. result.aHead = (uint)btm;
  111. //Set sign and exponent.
  112. result.SetSign( m.Sign() ); result.rdxExp = m.rdxExp;
  113. result.Reform(322); //Processing DoCutDown() etc.
  114. return result;
  115. }

sdfddsub.cpp : last modifiled at 2017/03/13 14:31:58(4,522 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).